<?php

namespace WeiPu\Shop\Http\Controllers;

use Dcat\Admin\Layout\Content;
use Dcat\Admin\Admin;
use Illuminate\Routing\Controller;
use Illuminate\Http\Request;
use WeiPu\Shop\Http\Controllers\InstallController;
use WeiPu\Shop\Models\PluginModel;
use WeiPu\Shop\ShopServiceProvider;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;

class ShopController extends Controller
{
    use ApiController;

    const URL = 'https://ruan.scmls.cn';
    // const URL = 'http://softp.cn';

    public function index(Content $content)
    {
        Admin::requireAssets('@weipu.shop');

        return $content
            ->title('商店')
            ->description('服务端软件应用商店')
            ->body(Admin::view('weipu.shop::index', ['url' => self::URL]));
    }

    /**
     * 发送验证码
     */
    public function sendCode(Request $request)
    {
        $email = $request->email;
        $endpoint = self::URL . "/api/user/sendEmail?email=" . $email;
        $client = new \GuzzleHttp\Client();

        $response = $client->request('GET', $endpoint, ['verify' => false]);
        $data = json_decode($response->getBody(), true);
        // dd($data );
        if ($data['code'] != 1) {
            return $this->error($data['msg']);
        }
        return $this->success($data['msg'], $data['data']);
    }

    /**
     * 查询支付订单
     */
    public function findPayOrder(Request $request)
    {
        $orderid = $request->orderid;
        $token = $request->token;
        $endpoint = self::URL . "/api/plug/getPayOrderStatus?orderid=" . $orderid . "&token=" . $token;
        $client = new \GuzzleHttp\Client();

        $response = $client->request('GET', $endpoint, ['verify' => false]);
        $data = json_decode($response->getBody(), true);

        // dd($data );
        if ($data['code'] != 1) {
            return $this->error($data['msg']);
        }
        return $this->success($data['msg'], $data['data']);
    }

    /**
     * 获取软件
     */
    public function getSoftWares()
    {

        $endpoint = self::URL . "/api/plug/index?search=" . request()->search;
        $client = new \GuzzleHttp\Client();

        $response = $client->request('GET', $endpoint, ['verify' => false]);
        $data = json_decode($response->getBody(), true);
        // dd($data['data']);
        // 判断是否安装
        if (isset($data['data']) && is_array($data['data'])) {
            foreach ($data['data'] as $key => &$value) {
                # code...
                $version = PluginModel::where('name', $value['name'])->value('version');
                $value['iversion'] = $version ? $version : 0;
                if (strstr($value['author'], '@')) {
                    $value['author'] = explode('@', $value['author'])[0];
                }
            }
        }

        return response()->json($data);
    }

    /**
     * 安装插件
     */
    public function installSoftWare(Request $request)
    {
        // 测试
        // $Install = new InstallController();
        // $Install->installZip('test');
        // die;
        $name = $request->name;
        $token = $request->token;
        $pass = $request->pass;
        if (!$pass) {
            return $this->error('请输入安装密码');
        } else {
            $ipass = ShopServiceProvider::setting('ipass');
            if ($pass != $ipass) {
                return $this->error('安装密码错误');
            }
        }
        $rinstall = $request->rinstall;
        $endpoint = self::URL . "/api/plug/down?name=" . $name . "&token=" . $token . "&rinstall=" . $rinstall;
        // dd($endpoint);
        $client = new \GuzzleHttp\Client();

        $response = $client->request('GET', $endpoint, ['http_errors' => false, 'verify' => false]);

        $data = json_decode($response->getBody(), true);

        // dd($data );
        if ($data['code'] != 1) {
            return $this->result($data['msg'], $data['data'], $data['code']);
        }

        $plugId = PluginModel::where('name', $data['data']['name'])->value('id');
        $updateSql = false;
        if ($plugId) {
            // 不覆盖
            if (!$rinstall) {
                return $this->success('覆盖安装', 'rinstall');
            } else {
                // 升级数据库
                $updateSql = true;
            }
        }

        // // 测试
        // $Install = new InstallController();
        // $result = $Install->installLog($name, $data['data']);

        // die;
        if (!$data['data']['file']) {
            return $this->error('插件包地址不存在');
        }

        $Install = new InstallController();
        // 判断file是否有https
        if (strstr($data['data']['file'], 'http')) {
            $filePath = $data['data']['file'];
        } else {
            $filePath = self::URL . $data['data']['file'];
        } 
        // 下载zip
        $path = $Install->downZip($filePath, $data['data']['name'], $data['data']['is_app']);

        if ($path) {
            $names = $data['data']['name'];
            $titles = $data['data']['describe'];
            $zipPass = $data['data']['zip_pass'];
            $paceappsName = $data['data']['paceapps_name'];
            $isApp = $data['data']['is_app'];
            // 解压zip
            $result = $Install->unZip($zipPass, $path, $name);

            if ($result !== true) {
                return $this->error($result);
            }
            // 检查是否是完整的应用
            if ($isApp && $isApp === 1) {
                $checkInstall = $this->handelInstallSoftWaresApp($names, $updateSql);
                // 没有安装成功
                if ($checkInstall !== true) {
                    $Install->delZip($name); // 删除zip
                    $data['msg'] = $checkInstall;
                    return response()->json($data);
                } else {
                    // 写入安装日志
                    $data['data']['conf'] = '';
                    $result = $Install->installLog($data['data'], $names);
                }
            }else{
                // 通过是否存在多应用
                if (strstr($paceappsName, ',')) {
                    $arrName = explode(',', $paceappsName);
                    $arrTitle = explode(',', $titles);
                } else {
                    $arrName = [$names];
                    $arrTitle = [$titles];
                }

                if (is_array($arrName)) {
                    foreach ($arrName as $key => $value) {
                        $title = $arrTitle[$key];
                        // 判断sql是否存在
                        $isTable = Schema::hasTable($value);
                        if ($isTable && !$updateSql) {
                            $Install->delZip($name); // 删除zip
                            return $this->error('检查到' . $value . '数据表已存在，请先删除数据表');
                        }
                        $installResult = $this->handelInstallSoftWares($data, $value, $title, $result, $Install, $updateSql); // 递归安装
                        if (!$installResult['code']) {
                            return $this->error($installResult['msg']);
                        }
                    }
                }
            }
            // die;
            // 解压成功
            // dd(($data['data']['name']));
            $Install->delZip($name);
        } else {
            return $this->error('插件下载失败');
        }
        
        return response()->json($data);
    }

    /**
     * 处理安装完整的应用
     */
    protected function handelInstallSoftWaresApp($names, $updateSql)
    {
        // 源文件夹路径  
        $sourceFolder = storage_path($names);
        // 如果是扩展包
        if ($names == 'vendor') {
            $targetFolder = base_path($names); 
        } else {
            // 目标文件夹路径  
            $targetFolder = base_path('addons' . DIRECTORY_SEPARATOR .$names);  
            if (File::isDirectory($targetFolder) && !$updateSql) { 
                return '请手动删除本地的' . $names . '文件夹';
            }
            $sqlName = $updateSql ? 'update.sql' : 'install.sql';
            // 更新
            $sqlPath = $sourceFolder . DIRECTORY_SEPARATOR . $sqlName;
            if (file_exists($sqlPath)) {
                if ($updateSql) {
                    self::handelUpdateSql($sqlPath);
                } else {
                    // 导入sql
                    $sql = File::get($sqlPath);
                    if ($sql) {
                        DB::unprepared($sql);
                    }
                }
            }
        }
       
        File::copyDirectory($sourceFolder, $targetFolder);
        
        return true;
    }

    /**
     * 处理更新的sql
     */
    protected static function handelUpdateSql($sqlPath)
    {
        // 使用 file() 函数将文件内容读入数组，并忽略每行的换行符  
        $sqlArr = file($sqlPath, FILE_IGNORE_NEW_LINES); 
        // 去除空 
        $newSqlArr = array_filter($sqlArr);  
        // 如果你想要处理文件内容，可以遍历数组  
        foreach ($newSqlArr as $line) {  
            // dd($line);
            // 对每一行进行处理  
            $sqlLine = explode('=>', $line);
            $tableColumn = explode('.', $sqlLine[0]);
            // dump($sqlLine[1]);
            // 判断字段
            if (isset($tableColumn[0]) && isset($tableColumn[1])) {
                if (!Schema::hasColumn(trim($tableColumn[0]), trim($tableColumn[1]))) {  
                    // 字段不存在  
                    DB::unprepared($sqlLine[1]); 
                }
            }
            // 判断数据表
            if (isset($tableColumn[0]) && !isset($tableColumn[1])) {
                if (!Schema::hasTable(trim($tableColumn[0]))) {
                    DB::unprepared($sqlLine[1]); 
                }
            }
        }
    }

    /**
     * 处理多个应用安装
     */
    protected function handelInstallSoftWares($data, $name, $title, $result, $Install, $updateSql)
    {
        if (is_dir(storage_path($name))) {
            $result = $Install->installZip($name, $title);
            // dd($result,1);
            if (!$result) {
                return $this->arrError('插件包异常');
            } else {
                $data['data']['conf'] = json_encode($result);
            }
            // 安装sql
            $result = $Install->installSql($name, $updateSql);
            // dd($result);
            if (!$result) {
                // 删除文件
                $this->delFiles($name, $Install);
                return $this->arrError('安装数据库异常');
            } else {
                // 写入安装日志
                $result = $Install->installLog($data['data'], $name);
                // dd($result);
                // 删除安装文件
                // 删除文件
                $this->delFiles($name, $Install);
                return $this->arrSuccess('ok');
            }
        } else {
            // 删除文件
            $this->delFiles($name, $Install);
            return $this->arrError('插件包读取失败');
        }
    }

    /**
     * 删除文件
     */
    protected function delFiles($name, $Install)
    {
        $tableDir = storage_path($name);
        File::cleanDirectory($tableDir);
        // 删除目录
        File::deleteDirectory($tableDir, $preserve = false);
        $Install->delZip($name);
    }

    /**
     * 远程登录
     */
    public function loginSoftWare(Request $request)
    {
        $account = $request->account;
        $password = $request->password;

        $endpoint = self::URL . "/api/user/login";
        $client = new \GuzzleHttp\Client();

        $response = $client->request('POST', $endpoint, [
            'form_params' => [
                'account' => $account,
                'password' => $password,
            ],
            'verify' => false
        ]);

        $data = json_decode($response->getBody(), true);

        return response()->json($data);
    }

    /**
     * 卸载软件
     */
    public function uninstallSoftWare(Request $request)
    {
        $name = $request->name;
        $paceappsName = $request->paceapps_name;
        $describe = $request->title;
        $pass = $request->pass;
        if (!$pass) {
            return $this->error('请输入卸载密码');
        } else {
            $ipass = ShopServiceProvider::setting('upass');
            if ($pass != $ipass) {
                return $this->error('卸载密码错误');
            }
        }
        $Install = new InstallController();

        $result = $Install->uninstall($name, $paceappsName, $describe);

        return $this->success('卸载成功', $result);
    }
}
